#include<stdio.h>
#include<Mesh_IO/Mesh_IO.h>

#include<Algorithm/points_cloud_algorithm.h>
#include<tool/libcell_tools_algorithm.h>

#include<libcell_macros.h>
#include <Arcroll.h>
#include <Dense>
#include<SVD>
using namespace Eigen;

// Node* get_cluster_pionts_from_mesh1(Mesh * m,double r);
#include<Mesh/Mesh_Operator.h>
#include <tool/libcell_kd_node_iterator.h>
#include<tool/libcell_octree_iterator.h>

#define quote lib_cell_quote

static double get_fac_from_model(Mesh* model)
{
	double * box=mesh_compute_bounding_box(model);
	double bound[3]={box[3]-box[0],box[4]-box[1] ,box[5]-box[2]};
	for(int i=0;i<2;i++)
    {
        for(int j=0;j<2;j++)
        {
            if(bound[j]<bound[j+1])
            {
                double temp=bound[j];
                bound[j]=bound[j+1];
                bound[j+1]=temp;
            }
        }
    }
  	double re= 0.192/bound[0];
  	printf("bound :%lf %lf %lf\n",bound[0],bound[1],bound[2]);


	free(box);
	return re;
}

static void points_cloud_compute_normal1(Node* n,KD_Node*kdtree,double r)
{
	clock_t t = clock();
	int i=0;
	double* normal=NULL;
	for(Node* nit=n;nit!=NULL;nit=(Node*)(nit->Next))
	{

		template_v*v=(template_v*)(nit->value);
		Node* n1=kd_tree_find_nearest_sphere(v,r,kdtree);
		double** axis=compute_pca_result(n1);
		normal=(double*)malloc(sizeof(double)*3);
		v->prop=normal;
		if(axis==NULL)
		{
			normal[0]=0;normal[1]=0;normal[2]=1.0;
		}
		else
		{
			normal[0]=axis[0][0];normal[1]=axis[1][0];normal[2]=axis[2][0];
			for(int j=0;j<v->point_size;j++)
			{
				free(axis[j]);
			}
			free(axis);
		}

		free_node(n1);
		i++;
	}
	printf("运行时间%.5f秒:%d\n", (double)(clock() - t) / CLOCKS_PER_SEC,0);
}



void compuate_scene_normal(Mesh* m,KD_Node *kdtree,double r)
{
	Node*n=NULL; 
	for(auto vit=m->v_begin(m);vit!=m->v_end(m);vit++)
	{
		n=node_overlying(n,quote(vit));
	}
	points_cloud_compute_normal1(n,kdtree,r);
	for(Node* nit=n;nit!=NULL;nit=(Node*)(nit->Next))
	{
		template_v* v=(template_v*)(nit->value);
		double* normal= (double*)(v->prop);
		if(normal[2]>0)
		{
			normal[0]=-normal[0]; normal[1]=-normal[1];normal[2]=-normal[2];
		}
	}
	free_node(n);
}

// void my_read(char* filename,Mesh* m)
// {
// 	char * p= filename_
// }


// double* mesh_compute_bounding_box(Mesh* m);
   // printf("bounds :%lf %lf %lf\n",bound[0],bound[1],bound[2]); 
   //  double fac =0.192/bound[0];
   //  //double fac=0.14/bound[1];

   //  for(int i=0;i<cloud.size();i++)
   //  {
   //      cloud.points[i].x*=fac;
   //      cloud.points[i].y*=fac;
   //      cloud.points[i].z*=fac;
   //  }
   //  return fac;


void oc_node_init_from_node(OC_Node*ocn,Mesh *m)
{
	Node* n=NULL;
	for(auto vit=m->v_begin(m);vit!=m->v_end(m);vit++)
	{
		n=node_overlying(n,quote(vit));

	} 
	oc_node_init_from_node(ocn,n);
	free_node(n);
}


OC_Node*  get_oc_node_according_to_size(Mesh * m,double len )
{
	OC_Node* ocn=(OC_Node*)malloc(sizeof(OC_Node));
 	oc_node_init(ocn);
    
   	auto vit=m->v_begin(m); 
    template_v* v=quote(vit);

    ocn->loc_min[0]=v->point[0];  ocn->loc_min[1]=v->point[1]; ocn->loc_min[2]=v->point[2];
    ocn->loc_max[0]=v->point[0];  ocn->loc_max[1]=v->point[1]; ocn->loc_max[2]=v->point[2];

    for(;vit!=m->v_end(m);vit++)
    {
        v=quote(vit); 
    	ocn->value=node_overlying(ocn->value,v);
        for(int i=0;i<3;i++)
        {
            v->point[i]>ocn->loc_max[i]?(ocn->loc_max[i]=v->point[i]):(v->point[i]<ocn->loc_min[i]?(ocn->loc_min[i]=v->point[i]):(i=i));
        }
    }    
   	double bound[3]={ocn->loc_max[0]-ocn->loc_min[0],ocn->loc_max[1]-ocn->loc_min[1],ocn->loc_max[2]-ocn->loc_min[2] };  	
	for(int i=0;i<2;i++)
    {
        for(int j=0;j<2;j++)
        {
            if(bound[j]<bound[j+1])
            {
                double temp=bound[j];
                bound[j]=bound[j+1];
                bound[j+1]=temp;
            }
        }
    }
    int k=0;double temp_len=len;
    for(int i=0;i<90;i++)
    {
    	temp_len=temp_len*2;
    	k=i+1;
    	if(temp_len>bound[0])
    	{
    		break;
    	}
    }
    printf("k:%d %lf %lf\n",k,bound[0],temp_len);


  	ocn->loc_max[0]=ocn->loc_min[0]+temp_len;ocn->loc_max[1]=ocn->loc_min[1]+temp_len;ocn->loc_max[2]=ocn->loc_min[2]+temp_len;


  	for(int i=0;i<k;i++)
  	{

  		oc_node_divide_all_leaves(ocn);	
  	}
   	return ocn;
}


Mesh* downsampling_points(Mesh *m, double len )
{
	OC_Node*ocn= get_oc_node_according_to_size(m,len);
	
	Mesh * re=(Mesh*)malloc(sizeof(Mesh));
	Mesh_init(re);
	double p[3]={0,0,0};
	for(auto oit=octree_begin(ocn);oit!=octree_end(ocn);oit++ )
	{
		if(oit.it->value!=NULL)
		{
			//p[0]=(oit.it->loc_min[0]+oit.it->loc_max[0])/2.0;	p[1]=(oit.it->loc_min[1]+oit.it->loc_max[1])/2.0;	p[2]=(oit.it->loc_min[2]+oit.it->loc_max[2])/2.0;
			memset(p,0,sizeof(double)*3);
			double sum=0;
			for(Node* nit=oit.it->value;nit!=NULL;nit=(Node*)(nit->Next))
			{
				template_v* v1=(template_v*)(nit->value);
				p[0]+=v1->point[0];p[1]+=v1->point[1];p[2]+=v1->point[2];
				
				sum+=1;
			}	
			p[0]/=sum;p[1]/=sum;p[2]/=sum;

			re->create_vertexv(re,p ,3);
		}
	}
	oc_node_free(ocn);
	return re;
}

//***************
//tree给出点云数据
//v是某点
//***************
Node* get_one_cluster_from_one_point(Int_RB_Tree* tree ,KD_Node*kdtree,double dis,double theta,template_v* v )
{
	Int_RB_Tree * tree1=(Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
	int_rb_tree_init(tree1); 

	Node* re=NULL;
	Node* temp_n=NULL;temp_n=node_overlying(temp_n,v);
	re=node_overlying(re,v);
	tree1->insert(tree1,v->id,v); 



	while(temp_n!=NULL)
	{
		Node* temp_n2=NULL;
		for(Node* nit=temp_n;nit!=NULL;nit=(Node*)(nit->Next))
		{
			template_v* v1=(template_v*)(nit->value);
			double *normal1=(double*)(v1->prop);

			Node* temp_n1=kd_tree_find_nearest_sphere(v1,dis,kdtree );

			for(Node* nit1=temp_n1;nit1!=NULL;nit1=(Node*)(nit1->Next))
			{
				template_v* v2=(template_v*)(nit1->value);
				if(tree->find(tree,v2->id)==NULL)
				{
					continue;
				}
				if(tree1->find(tree1,v2->id)==NULL)
				{
					double* normal2=(double*)(v2->prop);
					if(inner_product(normal1,normal2,3)>theta)
					{
						temp_n2=node_overlying(temp_n2,v2);
						re=node_overlying(re,v2);
						tree1->insert(tree1,v2->id,v2);
					}
				}
			}
			free_node(temp_n1);
		}	
		free_node(temp_n);
		temp_n=temp_n2;
	}
	
	//free_kdnode(kdtree);
	int_rb_tree_free(tree1);
	return re;
}

Node*get_cluster_points(Mesh* m ,KD_Node* kdtree ,double dis,double theta)
{	
	Node* re=NULL;
	Int_RB_Tree* tree=(Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
	int_rb_tree_init(tree);
	for(auto vit=m->v_begin(m);vit!=m->v_end(m);vit++)
	{
		tree->insert(tree,quote(vit)->id,quote(vit));
	}
	while(tree->size>0)
	{
		auto trav=tree->begin(tree);
		printf("tree size:%d\n",tree->size);

		Node* n = get_one_cluster_from_one_point(tree,kdtree,dis,theta, (template_v*)(*trav) );
		for(Node* nit=n;nit!=NULL;nit=(Node*)(nit->Next))
		{
			template_v* v=(template_v*)(nit->value);
			tree->erase(tree,v->id);
		}
		if(node_size(n)>100)
		{
			re=node_overlying(re,n);
		}
		else
		{
			free_node(n);
		}
	}
	
	int_rb_tree_free(tree);
	return re;
}


typedef struct MY_TestViewer{
    
    Viewer_Something* vs;
    Viewer_Opengl_Interpreter* voi;
    Node* nit;

    void* prop;
}MY_TestViewer;

static inline void my_testviewer_init(MY_TestViewer* mytestv)
{
    mytestv->vs=NULL;
    mytestv->voi=NULL;
    mytestv->nit=NULL;
    mytestv->prop=NULL;
}


void my_test_key_fun(Viewer_Intera*vi)
{
    Interactor_GlobalInfo* g_info=vi->g_info;
    MY_TestViewer* myv=(MY_TestViewer*)(vi->representation);

    if(g_info->key_action==VIEWER_PRESS&&g_info->key==VIEWER_KEY_F)
    {
        printf("key  f \n");

       

        Viewer_Points* vp=(Viewer_Points*)(myv->vs->evolution);
		vp->set_color(vp,0.2,0.9,0.1,1.0);
       	
		Node* n=(Node*)(myv->nit->value);
		printf("%d\n",node_size(n));

		for(Node* nit=n;nit!=NULL;nit=(Node*)(nit->Next))
		{
			template_v* v=(template_v*)(nit->value);

			vp->color[v->id*4+0]=1.0;vp->color[v->id*4+1]=0.0;vp->color[v->id*4+2]=0.0;
		}

        // for(int i=0;i<vp->Data_rows;i++)
        // {
        //     xx[0]=myv->data[i*3+0];xx[1]=myv->data[i*3+1];xx[2]=myv->data[i*3+2];
        //     vp->Data[i*3+0]=yy[0];vp->Data[i*3+1]=yy[1];vp->Data[i*3+2]=yy[2];
        // }
     
        myv->voi->update_data(myv->voi); 

        if(myv->nit->Next!=NULL)
        {
        	myv->nit=(Node*)(myv->nit->Next);
        }

      
    }
    // else if(g_info->key_action==VIEWER_PRESS&&g_info->key==VIEWER_KEY_B)
    // {
    //     if(va->disappear_somethings!=NULL)
    //     {
    //         Node* temp_n=va->disappear_somethings;va->disappear_somethings=(Node*)(va->disappear_somethings->Next);
    //         Viewer_Something* vs=(Viewer_Something*)(temp_n->value);

    //         vs->disappear=0; 

    //         free(temp_n);
    //     }
    // }

}

static inline double get_kernel_fac(double r,double* temp)
{

	//double temp[3]={x[0]-center[0],x[1]-center[1],x[2]-center[2]  };
	return exp(-(temp[0]*temp[0]+temp[1]*temp[1]+temp[2]*temp[2])/(2*r*r))/(sqrt(2*M_PI)*r);

}

double * mean_shift(double* center,KD_Node*kdtree, Int_RB_Tree* tree,double r)
{
	double* shift=(double*)malloc(sizeof(double)*3);
	memset(shift,0,sizeof(double)*3);
	Vertex v;
	Vertex_init_(&v);
	v.point=center;
	v.point_size=3;
	Node*n= kd_tree_find_nearest_sphere(&v,r,kdtree);
	double sum=0;
	double temp[3]={0};
	//printf("%d\n",node_size(n));

	for(Node* nit=n;nit!=NULL;nit=(Node*)(nit->Next))
	{
		template_v* v1=(template_v*)(nit->value);
		tree->insert(tree,v1->id,v1);	
		temp[0]=v1->point[0]-center[0];temp[1]=v1->point[1]-center[1];temp[2]=v1->point[2]-center[2];
		double fac=get_kernel_fac(r,temp);
		sum+=fac;
		shift[0]+=(fac*temp[0]);shift[1]+=(fac*temp[1]);shift[2]+=(fac*temp[2]);
	}
	free_node(n);
	if(sum!=0)
	{
		shift[0]/=sum;shift[1]/=sum;shift[2]/=sum;
	}
	return shift;
}


void  move_point_peak(double * center,KD_Node* kdtree,Int_RB_Tree* tree,double r,double theta)
{
	double theta_p=r*r*0.005;
	
	while(true)
	{
		double* shift=mean_shift(center,kdtree,tree,r);
		double len=shift[0]*shift[0]+shift[1]*shift[1]+shift[2]*shift[2];
		
		//printf("once :%lf %lf %lf \n",shift[0],shift[1],shift[2]);

		if(len<=theta_p)
		{
			free(shift);
			break;
		}
		center[0]+=shift[0];center[1]+=shift[1];center[2]+=shift[2];
		free(shift);
	}
}
typedef struct Mean_Shift_Cluster{
	Node*  n;
	double center[3];

}Mean_Shift_Cluster;
static inline void mean_shift_cluster_init(Mean_Shift_Cluster* msc)
{
	msc->n=NULL;
	msc->center[0]=0;msc->center[1]=0;msc->center[2]=0;

}


typedef struct  Mean_Shift_Prop{
	Mean_Shift_Cluster* msc;
	int votes;	

}Mean_Shift_Prop;
static inline void mean_shift_prop_init(Mean_Shift_Prop* msp)
{
	msp->msc=NULL;
	msp->votes=0;	

}


Mean_Shift_Prop*  my_find_mean_shift_prop(Node* n,Mean_Shift_Cluster* msc)
{
	for(Node* nit=n;nit!=NULL;nit=(Node*)(nit->Next))
	{
		Mean_Shift_Prop* msp=(Mean_Shift_Prop*)(nit->value);
		if(msp->msc==msc)
		{
			return msp;
		}
	}	
	return NULL;
}
Mean_Shift_Cluster* my_find_cluster(Node*n,double* center,double theta)
{
	for(Node* nit=n;nit!=NULL;nit=(Node*)(nit->Next))
	{
		Mean_Shift_Cluster* msc=(Mean_Shift_Cluster*)(nit->value);
		if( fabs(center[0]-msc->center[0])<theta&& fabs(center[1]-msc->center[1])<theta&& 
		fabs(center[2]-msc->center[2])<theta )
		{
			return msc;
		}
	}
	return NULL;
}


Node* mean_shift_cluster(Node* n , KD_Node*kdtree, double r,double theta)
{
	Node* re=NULL;
	for(Node* nit=n;nit!=NULL;nit=(Node*)(nit->Next))
	{
		template_v*v=(template_v*)(nit->value);
		double *center=(double*)malloc(sizeof(double)*3);
		memmove(center,v->point,sizeof(double)*3);
		Int_RB_Tree* tree=(Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
		int_rb_tree_init(tree);
		move_point_peak(center, kdtree,tree,r,theta);
		Mean_Shift_Cluster* msc =my_find_cluster(re,center,theta);

		if(msc==NULL)
		{
			msc=(Mean_Shift_Cluster*)malloc(sizeof(Mean_Shift_Cluster));
			mean_shift_cluster_init(msc);
			msc->center[0]=center[0];msc->center[1]=center[1];msc->center[2]=center[2];
			re=node_overlying(re,msc);
		}
		free(center);	

		for(auto it=tree->begin(tree);it.it!=NULL;it++ )
		{
			template_v* v1=(template_v*)(it.second);
			Node* n1= (Node*)(v1->prop);
			Mean_Shift_Prop* msp=my_find_mean_shift_prop(n1,msc);
			if(msp==NULL)
			{
				msp=(Mean_Shift_Prop*)malloc(sizeof(Mean_Shift_Prop));
				mean_shift_prop_init(msp);
				msp->votes=1;
				msp->msc=msc;
				
				n1=node_overlying(n1,msp);
				v1->prop=n1;
			}	
			else
			{
				msp->votes++;
			}
		}
		int_rb_tree_free(tree);
	}

	for(Node* nit=n;nit!=NULL;nit=(Node*)(nit->Next))
	{
		template_v*v=(template_v*)(nit->value);

		Mean_Shift_Prop* msp1=(Mean_Shift_Prop*)(((Node*)(v->prop) )->value);
		for(Node* nit1=(Node*)(v->prop);nit1!=NULL;nit1=(Node*)(nit1->Next))
		{
			Mean_Shift_Prop* msp=(Mean_Shift_Prop*)(nit1->value);
			if(msp->votes>msp1->votes)
			{
				msp1=msp;
			}
		}
		msp1->msc->n=node_overlying(msp1->msc->n,v);
	}
	for(Node* nit=re;nit!=NULL;nit=(Node*)(nit->Next))
	{
		Mean_Shift_Cluster* msc=(Mean_Shift_Cluster*)(nit->value);
		
		nit->value=msc->n;
		free(msc);
	}
	return re;
}
typedef struct DBScan_Prop
{
	//-1 未分类
	//1 核心点 ，2 边界点，3 噪点
	int mark;
	// 0 未被访问
	//1 已访问
	
	int is_visited;

}DBScan_Prop;

static inline void dbscan_prop_init(DBScan_Prop* dp)
{
	dp->mark=-1;
	dp->is_visited=0;

}



void dbscan_spread(template_v* v,KD_Node* kdtree,Int_RB_Tree* tree)
{
	

}


int main()
{
	printf("%lf\n",M_E);
	Mesh mesh ,mesh1;
	Mesh_init(&mesh);Mesh_init(&mesh1);

	_ReadPcd_(&mesh1,"111807.pcd");
 	_ReadPcd_(&mesh,"./cylinder1.pcd");
	
	double fac=get_fac_from_model(&mesh);


	mesh1*fac;

	Mesh* mesh2=downsampling_points(&mesh1,0.017);

	// OC_Node* ocn=  get_oc_node_according_to_size(&mesh1,0.01);
	

	KD_Node* kdtree= create_kd_tree_from_mesh(mesh2);

	//compuate_scene_normal(mesh2,kdtree,0.02);

	//Node* clus=get_cluster_points(mesh2,kdtree,0.02,0.8);

	Node* n_vertices=NULL;
	for(auto vit=mesh2->v_begin(mesh2);vit!=mesh2->v_end(mesh2);vit++)
	{
		n_vertices=node_overlying(n_vertices,quote(vit));	

	}	

	printf("node size: %d mesh2 v: %d\n",node_size(n_vertices),mesh2->num_v(mesh2));
	Node*clus= mean_shift_cluster(n_vertices ,kdtree, 0.060,0.025);
	

	// double center[3]={quote(mesh2->v_begin(mesh2))->point[0],quote(mesh2->v_begin(mesh2))->point[1],
	//  quote(mesh2->v_begin(mesh2))->point[2] };
	// Int_RB_Tree* tree=(Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
	// int_rb_tree_init(tree);
	// move_point_peak(center, kdtree,tree,0.03,0.005);

	printf("clus:%d\n",node_size(clus));



	Viewer_World_Manager vwm;
	viewer_world_manager_init(&vwm);
	Viewer_World* vw=vwm.create_world(&vwm,"中原动力位姿标注");
	vw->background_color[0]=244;	vw->background_color[1]=245;vw->background_color[2]=245;	

	Viewer_Opengl_Interpreter voi;
	Viewer_Arcroll* va= add_default_somethings(vw);

	MY_TestViewer* myv=(MY_TestViewer*)malloc(sizeof(MY_TestViewer));
	my_testviewer_init(myv);

	myv->nit=clus;
	myv->voi=&voi;



	Node*n=vw->create_something(vw,"Points");
	auto vs=(Viewer_Something*)(n->value);
	//vs->disappear=1;
	myv->vs=vs;

	auto vp=(Viewer_Points*)(vs->evolution);
	vp->pointsize=10.0;
	vp->Data_rows=mesh2->num_v(mesh2);

	vp->Data=(float*)malloc(sizeof(float)*3*vp->Data_rows);
	vp->set_color(vp,0.2,0.9,0.1,1.0);

	int i=0;
	for(auto vit=mesh2->v_begin(mesh2);vit!=mesh2->v_end(mesh2);vit++)
	{
		vp->Data[i*3+0]=quote(vit)->point[0];vp->Data[i*3+1]=quote(vit)->point[1];vp->Data[i*3+2]=quote(vit)->point[2];
		i++;
	}
	srand(time(NULL));

	// float colors[7][4]={
	// 	{0.9,0.8,0.3,1.0  },
	// 	{0.3 ,0.7,0.1,1.0},
	// 	{0.1,0.2,0.9,1.0 },
	// 	{0.6,0.2,0.8,1.0 },
	// 	{0.1,0.5,0.8,1.0},
	// 	{0.7,0.7,0.1,1.0},
	// 	{0.9,0.1,0.1,1.0}
	// };
	float color[4]={0};
	i=0;
	for(Node* nit=clus;nit!=NULL;nit=(Node*)(nit->Next))
	{
		Node* n1=(Node*)(nit->value);
		color[0]=(rand()%1000)/1000.0;color[1]=(rand()%1000)/1000.0;color[2]=(rand()%1000)/1000.0;
		for(Node* nit1=n1;nit1!=NULL;nit1=(Node*)(nit1->Next))
		{
			template_v* v=(template_v*)(nit1->value);
			//vp->color[v->id*4+0]=colors[i%7][0]+i*0.003;vp->color[v->id*4+1]=colors[i%7][1]+i*0.004;vp->color[v->id*4+2]=colors[i%7][2]+i*0.003;
			vp->color[v->id*4+0]=color[0];vp->color[v->id*4+1]=color[1]; vp->color[v->id*4+2]=color[2];

			vp->color[v->id*4+3]=1.0;
		}
		i++;
	}
	free_node(n);	


	// n=vw->create_something(vw,"Points");	
	// vs=(Viewer_Something*)(n->value);
	// // vs->disappear=1;
	// vp=(Viewer_Points*)(vs->evolution);
	// vp->Data_rows=0;
	// for(auto oit=octree_begin(ocn);oit!=octree_end(ocn);oit++ )
	// {
	// 	if(oit.it->value!=NULL)
	// 	{
	// 		vp->Data_rows++;
	// 	}
	// }
	// vp->Data=(float*)malloc(sizeof(float)*3*vp->Data_rows);
	// vp->set_color(vp,0.2,0.9,0.1,1.0);
	// vp->pointsize=12.0;
	// i=0;
	// for(auto oit=octree_begin(ocn);oit!=octree_end(ocn);oit++ )
	// {
	// 	if(oit.it->value!=NULL)
	// 	{
	// 		vp->Data[i*3+0]=(oit.it->loc_max[0]+oit.it->loc_min[0])/2.0 ;vp->Data[i*3+1]= (oit.it->loc_max[1]+oit.it->loc_min[1])/2.0;vp->Data[i*3+2]= (oit.it->loc_max[2]+oit.it->loc_min[2])/2.0;
	// 		i++;
	// 	}
	// }
	// free_node(n);


	
	// n = vw->create_something(vw,"Edges");

	// vs=(Viewer_Something*)(n->value);
	// //vs->disappear=1;	
	// auto ve=(Viewer_Edges*)(vs->evolution);
	// ve->Data_index_rows=mesh.num_v(mesh2);
	// ve->Data_rows=ve->Data_index_rows*2;
	
	// ve->Data=(float*)malloc(sizeof(float)*3*ve->Data_rows);
	// ve->Data_index=(unsigned int*)malloc(sizeof(unsigned int)*2*ve->Data_index_rows);
	// ve->color_rows=ve->Data_index_rows;
	// ve->set_color(ve,1.0,0.0,0.0,1.0);

	// i=0;
	// double fac1=0.05;
	// for(auto vit=mesh2->v_begin(mesh2);vit!=mesh2->v_end(mesh2);vit++)
	// {
	// 	ve->Data[(i*2+0)*3+0]=quote(vit)->point[0]; ve->Data[(i*2+0)*3+1]=quote(vit)->point[1];		ve->Data[(i*2+0)*3+2]=quote(vit)->point[2];

	// 	double*normal=(double*)(quote(vit)->prop);
		
	// 	//normalize(nbi->normal,3);

	// 	ve->Data[(i*2+1)*3+0]=quote(vit)->point[0]+fac1*normal[0]; ve->Data[(i*2+1)*3+1]=quote(vit)->point[1]+ fac1*normal[1];ve->Data[(i*2+1)*3+2]=quote(vit)->point[2]+fac1*normal[2];
 
	// 	ve->Data_index[i*2+0]=i*2+0; ve->Data_index[i*2+1]=i*2+1;
	// 	i++;
	// }

	// free_node(n);

	// n=vw->create_something(vw,"Intera" );
	
	// vs=(Viewer_Something*)(n->value);
 //    auto vi=(Viewer_Intera*)(vs->evolution);
 //    vi->representation=myv;
 //    vi->key_callback=my_test_key_fun;
	// free_node(n);




	viewer_opengl_interpreter_initn(&voi,&vwm);
	voi.interpreter(&voi);


	viewer_opengl_interpreter_free(&voi);
	viewer_world_manager_free(&vwm); 		

	Mesh_free(&mesh);Mesh_free(&mesh1);

	free_kdnode(kdtree);

	printf("enddddd\n");
	return 0;
}
